package controller;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import server.AgeDomain;
import server.AlexaUpdate;
import server.GetPage;
import server.GooglePageRank;
import server.Whois;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

import data.Data;
import data.Memcache;

@SuppressWarnings("serial")
public class DetailServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setContentType("text/plain");
		resp.setCharacterEncoding("utf-8");
		String path = ((HttpServletRequest)req).getRequestURI();
		
		StringTokenizer st = new StringTokenizer( path,"/");
        int count = st.countTokens(); 
        
        if(count!=2)
        {
        	
        	resp.getWriter().println("Bad request : "+req.getRequestURI());
        	resp.getWriter().close();
        	return ;
        	
        }

		// skip one token /sites/gooogle.com (remove sites)
		st.nextToken();
		String name = Utils.fomatDomain(URLDecoder.decode(st.nextToken(),"UTF-8"));
		
		try {
			if(Utils.checkDomain(name))
			{
				DBCollection coll = Data.data("domain");
				DBObject domains = coll.findOne(new BasicDBObject("name",name));
				resp.setHeader( "Cache-Control", "public, max-age=86400");
				resp.setHeader( "Expires", new Date(Calendar.getInstance().getTime().getTime()+24*60*60*1000).toGMTString());
				if(domains == null)
				{
					Random generator = new Random();
					int r = generator.nextInt(100000);
					DBObject domain = new BasicDBObject();
					domain.put("name", name);
					domain.put("update", new Date().getTime());
					domain.put("random", r);

					try {
						new GetPage(domain);
					} catch (Exception e) {
						// TODO: handle exception
					}
					try {
						new GooglePageRank(domain);
					} catch (Exception e) {
						// TODO: handle exception
					}
					try {
						new AgeDomain(domain);
					} catch (Exception e) {
						// TODO: handle exception
					}
					try {
						new AlexaUpdate(domain);
					} catch (Exception e) {
						// TODO: handle exception
					}
					try {
						new Whois(domain);
					} catch (Exception e) {
						// TODO: handle exception
					}
					
					try {
						Thread.sleep(5000);
						coll.save(domain);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					Memcache.setMemcache("last-update", domain.get("name").toString());
					
					resp.sendRedirect("/domain/"+name);
				} else {
					if(domains.get("possex") == null || domains.get("possex") != null && !domains.get("possex").toString().equals("1"))
					{
						@SuppressWarnings({ "unchecked"})
						ArrayList<String> lastPing = (ArrayList<String>)Utils.cache.get("lastviews");
			        	
			        	
			        	if(lastPing != null && lastPing.size() > 0)
			        	{
				        	if(lastPing.size()>19)
				        	{
				        		lastPing.remove(0);
				        	}
				        	int check = 0;
				        	for (int i = 0; i < lastPing.size(); i++) {
								if(lastPing.get(i).equals(name))
								{
									check = 1;
								}
							}
				        	if(check == 0)
				        		lastPing.add(name);
				        		Utils.cache.put("lastviews", lastPing);
			        	} else {
			        		ArrayList<String> lastPings =  new ArrayList<String>();
			        		lastPings.add(name);
			        		Utils.cache.put("lastviews", lastPings);
			        	}
						
						DBCursor subdomain = coll.find(new BasicDBObject("domain",Utils.returnDomain(name))).limit(30);
						req.setAttribute("subdomain", subdomain);
						
						if(domains.get("googleAnalytics") != null && !domains.get("googleAnalytics").equals(""))
						{
							DBCursor googleAnalytic = coll.find(new BasicDBObject("googleAnalytics",domains.get("googleAnalytics"))).limit(20);
							req.setAttribute("googleAnalytic", googleAnalytic);
						}
						
						if(domains.get("googleAdsense") != null && !domains.get("googleAdsense").equals(""))
						{
							DBCursor googleAdsense = coll.find(new BasicDBObject("googleAdsense",domains.get("googleAdsense"))).limit(20);
							req.setAttribute("googleAdsense", googleAdsense);
						}
						
						if(domains.get("ip") != null && !domains.get("ip").toString().trim().equals(""))
						{
							DBCursor ip = coll.find(new BasicDBObject("ip",domains.get("ip"))).limit(20);
							req.setAttribute("ip", ip);
						}
						
						if(domains.get("random") != null && !domains.get("random").equals(""))
						{
							DBCursor random = coll.find(new BasicDBObject("random",domains.get("random"))).limit(20);
							req.setAttribute("random", random);
						}
						if(domains.get("ip")!=null&& !domains.get("ip").toString().trim().equals(""))
						{
							DBCursor sameDomain = coll.find(new BasicDBObject("ip",domains.get("ip"))).limit(15);
							req.setAttribute("sameDomain", sameDomain);
						}
						
						if(domains.get("siteRandom")==null)
						{
							Random generator = new Random();
							int r = generator.nextInt(1000000);
							DBCursor ldomain = coll.find(new BasicDBObject("random",new BasicDBObject("$lt",r))).sort(new BasicDBObject("random",-1)).limit(10);
							ArrayList<String> siteRandom = new ArrayList<String>();
							while(ldomain.hasNext())
							{
								DBObject dbObject = ldomain.next();
								siteRandom.add(dbObject.get("name").toString());
							}
							domains.put("siteRandom", siteRandom);
							coll.save(domains);
						}
						
						DBCollection colls = Data.data("link");
						DBCursor inlink = colls.find(new BasicDBObject("link",name)).limit(20);
						req.setAttribute("inlink", inlink);
						req.setAttribute("domain", domains);
						
						try {
							req.getRequestDispatcher("/detail.jsp").forward(req, resp);
						} catch (ServletException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} else {
						resp.sendError(resp.SC_NOT_FOUND,"Content removed because our policy !");
					}
				}
			} else {
				resp.getWriter().println("domain does not exist !");
			}
		} catch (Exception e) {
			resp.getWriter().println("Server is overloaded, please come back later, sorry for the inconvenience you !");
		}
	}
}
